
//import { assert} from "assert";
var assert = require("assert");
var iconv = require("iconv-lite");
import * as fs from "fs"
import { spawn } from "child_process";


export var ch = {
    艾瑞珂:0x1,
    塞思:0x2,
    吉利安姆:0x3,
    弗朗茨:0x4,
    摩达:0x5,
    瓦内萨:0x6,
    罗斯:0x7,
    梅米:0x8,
    科曼:0x9,
    加西亚:0xa,
    希尼亚斯:0xb,
    露忒:0xc,
    娜塔莎:0xd,
    库格:0xe,
    伊弗列姆:0xf,
    弗鲁迪:0x10,
    凯尔:0x11,
    阿米莉娅:0x12,
    阿斯雷:0x13,
    杰斯特:0x14,
    特缇斯:0x15,
    玛莉卡:0x16,
    塞勒夫:0x17,
    尤恩:0x18,
    拉切尔:0x19,
    多兹拉:0x1a,
    雷纳克:0x1c,
    杜塞尔:0x1d,
    梅尔:0x1e,
    诺鲁:0x1f,
    约书亚:0x20,
    西蕾尼:0x21,
    塔娜:0x22,
    利昂:0x23,
    奥尔森:0x24,
    格伦:0x25,
    塞莱娜:0x26,
    沃尔塔:0x27,
    阿维:0x28,
    凯瑟达:0x29,
    法德:0x2a,
    依修梅娅:0x2b,
    海登:0x2c,
    亡灵战士_利昂:0x3b,
    塞门:0x3c,
    萨玛南:0x3d,
    亡灵战士_诺鲁:0x3e,
    亡灵战士_尤恩:0x3f,
    利昂_魔:0x40,
    穆尔瓦:0x41,
    _奥尔森:0x42,
    _沃尔塔:0x43,
    _塞莱娜:0x44,
    __沃尔塔:0x45,
    普利肯:0x46,
    波恩:0x47,
    帕滋帕:0x48,
    魔物:0x49,
    萨尔:0x4a,
    诺贝拉:0x4b,
    马莱:0x4c,
    迪拉德:0x4d,
    西克斯:0x4e,
    巴勃罗:0x4f,
    _魔物:0x50,
    艾阿斯:0x51,
    卡莱尔:0x52,
    凯瑟达_:0x53,
    巴勃罗_:0x54,
    对战对手:0x55,
    魔物_:0x56,
    阿维_:0x57,
    肯普:0x5a,
    贝鲁奈:0x5b,
    魔物1:0x5c,
    魔物2:0x5d,
    魔物3:0x5e,
    魔物4:0x5f,
    奥尼尔:0x68,
    格伦2:0x69,
    松克:0x6a,
    彼加尔德:0x6b,
    利昂_魔2:0x6c,
    奥尔森_狂:0x6d,
    魔王:0xbe,
    弗雷利亚兵:0xc0,
    弗雷利亚兵1:0xc1,
    法德2:0xc5,
    海登2:0xc7,
    曼塞尔:0xc8,
    克利姆德:0xc9,
    塔拉:0xca,
    依修梅娅2:0xcb,
    天马传令兵:0xcc,
    罗斯顿兵:0xcd,
    罗斯顿兵2:0xce,
};

export var c = {
领主_男:0x1,
领主_女:0x2,
大领主_男:0x3,
大领主_女:0x4,
轻骑士_男:0x5,
轻骑士_女:0x6,
圣骑士_男:0x7,
圣骑士_女:0x8,
重甲骑士_男:0x9,
重甲骑士_女:0xa,
将军_男:0xb,
将军_女:0xc,
盗贼:0xd,
龙人_龙形态:0xe,
佣兵_男:0xf,
佣兵_女:0x10,
勇者_男:0x11,
勇者_女:0x12,
剑士_男:0x13,
剑士_女:0x14,
剑圣_男:0x15,
剑圣_女:0x16,
刺客_男:0x17,
刺客_女:0x18,
弓箭手_男:0x19,
弓箭手_女:0x1a,
狙击手_男:0x1b,
狙击手_女:0x1c,
丛林骑士_男:0x1d,
丛林骑士_女:0x1e,
龙骑士_男:0x1f,
龙骑士_女:0x20,
龙骑统帅_男:0x21,
龙骑统帅_女:0x22,
翼龙骑士_男:0x23,
翼龙骑士_女:0x24,
魔法师_男:0x25,
魔法师_女:0x26,
贤者_男:0x27,
贤者_女:0x28,
魔法骑士_男:0x29,
魔法骑士_女:0x2a,
司祭_男:0x2b,
司祭_女:0x2c,
巫师_男:0x2d,
巫师_女:0x2e,
德鲁伊_男:0x2f,
德鲁伊_女:0x30,
召唤士_男:0x31,
召唤士_女:0x32,
侠盗:0x33,
恶魔蛋:0x34,
重骑士_男:0x35,
重骑士_女:0x36,
新人士兵2:0x37,
年轻战士3:0x38,
见习魔法师3:0x39,
新人士兵3:0x3a,
龙人_穆尔德:0x3b,
龙人_梅尔:0x3c,
年轻战士1:0x3d,
见习魔法师1:0x3e,
战士:0x3f,
勇士:0x40,
山贼:0x41,
海贼:0x42,
狂战士:0x43,
修道士:0x44,
神官:0x45,
吟游诗人:0x46,
新人士兵1:0x47,
天马骑士:0x48,
隼骑士:0x49,
修女:0x4a,
神官骑士:0x4b,
女武神:0x4c,
舞者:0x4d,
士兵:0x4e,
亡灵巫师:0x4f,
军舰:0x50,
亡灵战士:0x51,
僵尸:0x52,
木乃伊:0x53,
骷髅兵:0x54,
骷髅兵_弓箭:0x55,
骷髅战士:0x56,
骷髅战士_弓箭:0x57,
毒蜘蛛:0x58,
毒巨蛛:0x59,
独眼巨人:0x5a,
魔刹犬:0x5b,
三头地狱犬:0x5c,
战鬼:0x5d,
半人马:0x5e,
眼魔:0x5f,
大眼魔:0x60,
石化妖:0x61,
恶魔蛋2:0x62,
石像鬼:0x63,
亡灵石像鬼:0x64,
僵尸龙:0x65,
魔王:0x66,
弩车:0x67,
弩车1:0x68,
弩车2:0x69,
弩车3:0x6a,
弩车4:0x6b,
弩车5:0x6c,
孩子_男:0x6d,
孩子_女:0x6e,
市民_男:0x6f,
市民_女:0x70,
市民_男1:0x71,
市民_女1:0x72,
贵族:0x73,
女王:0x74,
王子:0x75,
公主:0x76,
无:0x77,
吟游诗人_昏迷:0x78,
运输队:0x79,
教皇:0x7a,
王子_昏迷:0x7b,
独眼巨人2:0x7c,
毒巨蛛1:0x7d,
年轻战士2:0x7e,
见习魔法师2:0x7f,
};

export var i = {
铁剑:0x01,
细身剑:0x02,
钢剑:0x03,
银剑:0x04,
铁之大剑:0x05,
钢之大剑:0x06,
银之大剑:0x07,
毒剑:0x08,
突刺剑:0x09,
玛尼_卡缇:0x0A,
勇者之剑:0x0B,
新月刃:0x0C,
必杀刃:0x0D,
破甲剑:0x0E,
斩龙剑:0x0F,
光之剑:0x10,
卢尼之剑:0x11,
破枪剑:0x12,
斩马刀:0x13,
铁枪:0x14,
细枪:0x15,
钢枪:0x16,
银枪:0x17,
毒枪:0x18,
勇者之枪:0x19,
必杀枪:0x1A,
　 刺马枪:0x1B,
投枪:0x1C,
锁链枪:0x1D,
破斧枪:0x1E,
铁斧:0x1F,
钢斧:0x20,
银斧:0x21,
毒斧:0x22,
勇者之斧:0x23,
必杀斧:0x24,
战戟:0x25,
战锤:0x26,
恶魔之斧:0x27,
投斧:0x28,
回旋斧:0x29,
破剑斧:0x2A,
弑剑斧:0x2B,
轻斧:0x2C,
铁弓:0x2D,
钢弓:0x2E,
银弓:0x2F,
毒弓:0x30,
必杀弓:0x31,
勇者之弓:0x32,
短弓:0x33,
长弓:0x34,
长弩:0x35,
钢铁弩:0x36,
必杀弩:0x37,
火炎:0x38,
闪电:0x39,
地狱业火:0x3A,
雷暴:0x3B,
终末之冬:0x3C,
弗尔布雷斯:0x3D,
艾克斯迦利瓦:0x3E,
闪光:0x3F,
阳光:0x40,
神圣之光:0x41,
净化之光:0x42,
光轮:0x43,
露丝:0x44,
熔流:0x45,
月光:0x46,
吸星术:0x47,
月食:0x48,
诺斯费拉特:0x49,
格雷普尼尔:0x4A,
回复之杖:0x4B,
治疗之杖:0x4C,
痊愈之杖:0x4D,
治愈之杖:0x4E,
生命之杖:0x4F,
复原之杖:0x50,
沉默之杖:0x51,
睡眠之杖:0x52,
狂乱之杖:0x53,
传送杖:0x54,
援救杖:0x55,
松明之杖:0x56,
修理之杖:0x57,
开锁杖:0x58,
魔防之杖:0x59,
龙斧:0x5A,
天使之衣:0x5B,
能量之环:0x5C,
秘传之書:0x5D,
疾风之羽:0x5E,
女神像:0x5F,
龙盾:0x60,
魔法护身符:0x61,
靴子:0x62,
体格指环:0x63,
英雄之证:0x64,
骑士勋章:0x65,
猎户座之箭:0x66,
天空之鞭:0x67,
指引之戒:0x68,
宝箱钥匙:0x69,
门钥匙:0x6A,
盗贼钥匙:0x6B,
伤药:0x6C,
特效药:0x6D,
圣水:0x6E,
消毒药:0x6F,
火把:0x70,
菲利的护符:0x71,
会员卡:0x72,
银卡:0x73,
白色宝玉:0x74,
青色宝玉:0x75,
赤色宝玉:0x76,
金币:0x77,
勒金雷布:0x78,
宝箱钥匙2:0x79,
火炎爆弹:0x7A,
光之结界:0x7B,
波布罗的护符:0x7C,
法拉之力:0x7D,
妮妮斯的守护:0x7E,
托尔之怒:0x7F,
塞奇之祈祷:0x80,
斩魔之剑:0x81,
袭魔之枪:0x82,
断魔之斧:0x83,
破魔之弓:0x84,
吉克林迪:0x85,
战斧:0x86,
伊瓦尔迪:0x87,
统帅之证:0x88,
知惠之书:0x89,
天之刻印:0x8A,
利爪:0x8B,
拉特娜:0x8C,
龙枪:0x8D,
彼德弗尼尔:0x8E,
纳格尔法尔:0x8F,
死亡的吐息:0x90,
阿德姆拉:0x91,
吉克穆特:0x92,
贾尔姆:0x93,
尼兹赫古:0x94,
刺突枪:0x95,
短枪:0x96,
霸者之证:0x97,
月之腕轮:0x98,
太阳之腕轮:0x99,
_１Ｇ:0x9A,
_５Ｇ:0x9B,
_１０Ｇ:0x9C,
_５０Ｇ:0x9D,
_１００Ｇ:0x9E,
_３０００Ｇ:0x9F,
_５０００Ｇ:0xA0,
风之剑:0xA1,
伤药1:0xA2,
伤药2:0xA3,
伤药3:0xA4,
舞蹈:0xA5,
漆黑的恶梦:0xA6,
魔石的碎片:0xA7,
不净的魔光:0xA8,
破灭的魔拳:0xA9,
龙石:0xAA,
魔幻的波动:0xAB,
暗黑的魔弹:0xAC,
腐爪:0xAD,
腐长爪:0xAE,
毒爪:0xAF,
猛毒之爪:0xB0,
灼热之牙:0xB1,
焦热之牙:0xB2,
邪眼光线:0xB3,
魔眼光线:0xB4,
石化光线:0xB5,
风之刃:0xB6,
修娜之实:0xB7,
_１５０Ｇ:0xB8,
_２００Ｇ:0xB9,
黑色宝玉:0xBA,
金色宝玉:0xBB,

};

var 角色 = [];
var 角色列表 = [];
var 角色表 = {};
var 角色对话头像 = {};
var 角色介绍 = [];

var 职业 = [];
var 职业表 = {};
var 职业描述 = [];

var 道具 = [];
var 道具表 = {};
var 道具说明 = [];

//初始化各种表
for (const key in i) {
    道具表[key] = i[key];
}

for(const key in c){
    职业表[key] = c[key];
}

for(const key in ch){
    角色表[key] = ch[key];
}

var tohex = (v)=>{
    return '0x'+v.toString(16);
};

var getvalue = (a,v)=>{
    if(typeof(a)=="number"){
        return a;
    }
    a = a || v;
    return a;
}

export var set道具 = {
createASM:(file:fs.WriteStream)=>{
    var code = '';
    道具.forEach((v,k)=>{
        if(v){
            v.d.createASM(file);
        }
    });
},
设置道具:(索引,道具名,道具描述,道具说明)=>{
    var data:any = {
        道具描述:道具描述,
        道具名:道具名,
        道具说明:道具说明,
        id:索引
    };
    道具[索引] = data;
    道具表[道具名] = 索引;
    var d = {
    createASM:(file:fs.WriteStream)=>{
        var code = '';
        var addcode = (name,value)=>{
            if(value!=undefined){
                code += `[${data.id}].${name} = ${value},\n`;
            }
        };

        addcode("u00_",newText(data.道具名));
        addcode("u02_",newText(data.道具描述));
        addcode("u04_",newText(data.道具说明));
        addcode("u07_",data.类型);
        if(data.武器){
            data.特殊属性 = data.特殊属性 | 0;
            data.特殊属性 |= 1;
        }
        if(data.无限耐久){
            data.特殊属性 |= 0x8;
        }
        if(data.魔法剑){
            file魔法武器.write(`
set_item_anime(${data.id},${data.魔法剑}),
`);
            data.特殊属性 |= 0x40;

        }
        addcode("u08_",data.特殊属性);

        if(data.基础属性){
            addcode("u14_",data.基础属性.耐久)
            addcode("u15_",data.基础属性.攻击)
            addcode("u16_",data.基础属性.命中)
            addcode("u17_",data.基础属性.重量)
            addcode("u18_",data.基础属性.必杀)
            addcode("u19_",data.基础属性.射程)
            addcode("u1C_",data.基础属性.单价)
        }

        if(data.附加能力){
            var _code = ``;
            var l:[] = data.附加能力;
            l.forEach((v,k)=>{
                if(v){
                    _code += `${v},`
                }
                else{
                    _code += `0,`;
                }
            });
            addcode("u0C_",`(u32)(const u8[]){${_code}}`);
        }

        if(data.召唤){
            var char_id = get_char(data.召唤.角色)
            var item_code = '';
            var items = data.召唤.武器;
            for(var i=0;i<4;i++){
                if(items[i]){
                    item_code += `,${get_item(items[i])}`;
                }
                else{
                    item_code += `,0`;
                }
            }
            file召唤.write(`
set_item_summon(0x${data.id.toString(16)},${char_id}),
            `);
            file召唤道具.write(`
set_summon_item(0x${char_id.toString(16)}${item_code}),
`);
            file召唤职业.write(`
set_summon_class(0x${char_id.toString(16)},${get_class(data.召唤.职业)}),
`);
        }

        if(data.限制角色){
            var d:[] = data.限制角色;
            d.forEach((v,k)=>{
                file道具限制.write(`
set_item_limit(${get_char(v)},${data.id}),
                `);
            });
        }

        addcode("u1C_",data.熟练度);
        addcode("u20_",data.熟练度获得);

        addcode("u1D_",data.图标);//图标
        addcode("u1E_",data.道具效果);
        addcode("u1F_",data.武器效果);
        if(file){
            file.write(code);
        }
        return code;
    },
    类型:{
    剑:0,
	枪:1,
	斧:2,
	弓:3,
	杖:4,
	理:5,
	光:6,
	暗:7,
	道具:9,
	龙石_魔物专用:0xb,
	指环:0xc,
	火龙石:0x11,
	指环2:0x12,
    },
    设置类型:(类型)=>{
        data.类型 = 类型;
    },
    基础属性:(v:{
        耐久?:number,
        攻击?:number,
        命中?:number,
        重量?:number,
        必杀?:number,
        射程?:number,
        单价?:number,
    })=>{
        v.耐久 = getvalue(v.耐久,1)
        v.攻击 = getvalue(v.攻击,0)
        v.命中 = getvalue(v.命中,50)
        v.重量 = getvalue(v.重量,0)
        v.必杀 = getvalue(v.必杀,0)
        v.射程 = getvalue(v.射程,0x11);
        v.单价 = getvalue(v.单价,0)
        if(v.攻击!=undefined){
            data.武器 = true;
        }
        if(v.耐久<0){
            data.无限耐久 = true;
        }
        data.基础属性 = v;

    },
    道具效果:(v={
        愈合:false,
        修补:false,
        恢复:false,
        物理:false,
        加固:false,
        还原:false,
        松明:false,
    })=>{
        data.道具效果 = 0;
    },
    武器效果:(v={
        毒药:false,
        吸血:false,
        伤害减半:false,
        反噬:false,
        石化:false,
    })=>{
        var t = {
            毒药:0x1,
            吸血:0x2,
            伤害减半:0x3,
            反噬:0x4,
            石化:0x5,
        };
        var value = 0;
        for (const key in v) {
            if(v[key]){
                value = t[key];
            }
        }
        data.武器效果 = value;
    },
    图标:(path)=>{
        data.图标 = path;
    },
    熟练度:(需求,获得量)=>{
        data.熟练度 = 需求;
        data.熟练度获得 = 获得量;
    },
    特殊属性:(v={
        武器:false,
        道具:false,
        魔法:false,
        杖:false,
        无限耐久:false,
        无法出售:false,
        两次攻击:false,
        魔法伤害:false,
        远程属性:false,
        反克效果:false,
        指环_修理杖 :false,
        BOSS专用:false,
        剑士专用:false,
        飞行守护:false,
        必杀守护:false,
        破防效果:false,
        女主专用:false,
        男主专用:false,
    })=>{
        var value = 0;
        var t = {
            武器:0x1,
            道具:0x2,
            魔法:0x2,
            杖:0x4,
            无限耐久:0x8,
            无法出售:0x10,
            两次攻击:0x20,
            魔法伤害:0x40,
            远程属性:0x80,
            反克效果:0x100,
            指环_修理杖 :0x200,
            BOSS专用:0x400,
            剑士专用:0x1000,
            飞行守护:0x4000,
            必杀守护:0x8000,
            破防效果:0x20000,
            女主专用:0x40000,
            男主专用:0x80000,
        };
        for (const key in v) {
            if(v[key]){
                value |= t[key];
            }
        }
        data.特殊属性 = v;
    },
    附加能力:(v={
        aHP : 0,
        a力量 : 0,
        a技术 : 0,
        a速度 : 0,
        a守备 : 0,
        a魔防 : 0,
        a幸运 : 0,
    })=>{
        var list = [];
        list.push(v.aHP);
        list.push(v.a力量);
        list.push(v.a技术);
        list.push(v.a速度);
        list.push(v.a守备);
        list.push(v.a魔防);
        list.push(v.a幸运);
        data.附加能力 = list;
    },
    职业特效:(v=[])=>{
    },

    扩展:{
        可召唤:(角色,职业,武器:[])=>{
            data.召唤 = {
                角色:角色,
                武器:武器,
                职业:职业,
            };
        },
        限制角色:(chars:[])=>{
            data.限制角色 = chars;
        },
        魔法剑:(id=0x1c)=>{
            data.魔法剑 = id;
        },
    },
    };
    data.d = d;
    return d;
},
};

export var set职业 = {
设置职业:(索引,职业名,职业介绍,肖像,地图静态形象)=>{
    职业表[职业名] = 索引;
    var data:any = {
        职业名:职业名,
        职业介绍:职业介绍,
        地图静态形象:地图静态形象,
        id:索引,
        肖像:肖像,
    };
    职业[索引] = data;
    职业描述[索引] = 职业介绍;
    return {
        createASM:()=>{
            var code = '';
            var addcode = (name,value)=>{
                if(value!=undefined){
                    code += `[${data.id}] = ${value}`;
                }
            };

            addcode("u00_",data.职业名);
            addcode("u02_",data.职业介绍);
            addcode('u06_',data.地图静态形象);
            addcode('u08_',data.肖像);
            if(data.附加能力值){
                addcode("u0B_",data.附加能力值.HP);
                addcode("u0C_",data.附加能力值.力量);
                addcode("u0D_",data.附加能力值.技术);
                addcode("u0E_",data.附加能力值.速度);
                addcode("u0F_",data.附加能力值.守备);
                addcode("u10_",data.附加能力值.魔防);
                addcode("u11_",data.附加能力值.体格);
                addcode("u12_",data.附加能力值.移动);
            }
            if(data.上限){
                addcode("u13_",data.上限.HP)
                addcode("u14_",data.上限.力量)
                addcode("u15_",data.上限.技术)
                addcode("u16_",data.上限.速度)
                addcode("u17_",data.上限.守备)
                addcode("u18_",data.上限.魔防)
                addcode("u19_",data.上限.体格)
            }

            if(data.成长){
                addcode("u1B_",data.成长.HP)
                addcode("u1C_",data.成长.力量)
                addcode("u1D_",data.成长.技术)
                addcode("u1E_",data.成长.速度)
                addcode("u1F_",data.成长.守备)
                addcode("u20_",data.成长.魔防)
                addcode("u21_",data.成长.运气)
            }

            if(data.转职加成){
                addcode("u22_",data.转职加成.HP)
                addcode("u23_",data.转职加成.力量)
                addcode("u24_",data.转职加成.技术)
                addcode("u25_",data.转职加成.速度)
                addcode("u26_",data.转职加成.守备)
                addcode("u27_",data.转职加成.魔防)
            }

            addcode('u28_',data.职业技能);

            if(data.武器熟练度){
                addcode("u2C_",data.武器熟练度.剑)
                addcode("u2D_",data.武器熟练度.枪)
                addcode("u2E_",data.武器熟练度.斧)
                addcode("u2F_",data.武器熟练度.弓)
                addcode("u30_",data.武器熟练度.杖)
                addcode("u31_",data.武器熟练度.理)
                addcode("u32_",data.武器熟练度.光)
                addcode("u33_",data.武器熟练度.暗)
            }
        },
        附加能力值:(v={
            HP :undefined,
            力量 :undefined,
            技术 :undefined,
            速度 :undefined,
            守备 :undefined,
            魔防 :undefined,
            体格 :undefined,
            移动 :undefined,
        })=>{
            data.附加能力值 = v;
        },
        上限:(v={
            HP : undefined,
            力量 : undefined,
            技术 : undefined,
            速度 : undefined,
            守备 : undefined,
            魔防 : undefined,
            体格 : undefined,
        })=>{
            data.上限 = v;
        },
        成长:(v={
            HP : undefined,
            力量 : undefined,
            技术 : undefined,
            速度 : undefined,
            守备 :undefined,
            魔防 :undefined,
            运气 : undefined,
        })=>{
            data.成长 = v;
        },
        转职加成:(v={
            HP :undefined,
            力量 :undefined,
            技术 :undefined,
            速度 :undefined,
            守备 :undefined,
            魔防 :undefined,
        })=>{
            data.转职加成 = v;
        },
        武器熟练度:(v={
            剑 : 0,
            枪 : 0,
            斧 : 0,
            弓 : 0,
            杖 : 0,
            理 : 0,
            光 : 0,
            暗 : 0,
        })=>{
            data.武器熟练度 = v;
        },
        战斗动画:(索引=[])=>{
            data.战斗动画 = 索引;
        },
        职业能力:(v={
            a再移动:false,
            a偷盗 : false,
            a使用盗贼钥匙 : false,
            a舞蹈 : false,
            a演奏 :false,
            a必杀加成 : false,
            a上位职业 : false,
            a运输队 : false,
            a战马 : false,
            a飞龙 : false,
            a飞马 : false,
            a压制 : false,
            a女性 : false,
            aboss : false,
            a魔王专用 : false,
            a剑士专用 : false,
            a龙_魔物专用 : false,
            a_10级 : false,
            a能力未知 : false,
            a三角攻击1 : false,
            a三角攻击2 : false,
            a瞬杀 : false,
            a封魔 : false,
            a召唤 : false,
            a女主角专用 : false,
            a男主角专用 : false,
            a琳专用 : false,
            a大贤者专用 : false
            ,})=>{

                var t = {
                    a再移动:1<<1,
                    a偷盗 : 1<<2,
                    a使用盗贼钥匙 : 1<<3,
                    a舞蹈 : 1<<4,
                    a演奏 :1<<5,
                    a必杀加成 : 1<<6,
                    a上位职业 : 1<<8,
                    a运输队 : 1<<9,
                    a战马 : 1<<10,
                    a飞龙 : 1<<11,
                    a飞马 : 1<<12,
                    a压制 : 1<<13,
                    a女性 : 1<<14,
                    aboss : 1<<15,
                    a魔王专用 : 1<<16,
                    a剑士专用 : 1<<17,
                    a龙_魔物专用 : 1<<18,
                    a_10级 : 1<<19,
                    a能力未知 : 1<<20,
                    a三角攻击1 : 1<<21,
                    a三角攻击2 : 1<<22,
                    a瞬杀 : 1<<25,
                    a封魔 : 1<<26,
                    a召唤 : 1<<27,
                    a女主角专用 : 1<<28,
                    a男主角专用 : 1<<29,
                    a琳专用 : 1<<30,
                    a大贤者专用 : 1<<31,
                };
                var value = 0;
                for (const k in v) {
                    if(v[k]){
                        value |= t[k];
                    }
                }

                data.职业能力 = value;
        },
    };
},
};

var convertText = (text)=>{
    //var text =
    var charp = {};
    var num = 0;
    var newText = '';
    var pos = 9;
    var hex = (v)=>{
        var vv = v.toString(16);
        if(vv.length==1){
            vv = '0' + vv;
        }
        return vv;
    }
    do{
        var a = text.match(/\[[^\]]+\]/);
        var len = undefined;
        if(a){
            len = a.index-1;
        }
        var tex = text.substr(0,len);
        newText += tex;
        if(a==null){
            if(num==0){
                return text;
            }
            break;
        }
        //console.log(a);
        var char = a[0];
        var _pos = char.match(/\>+\]/);
        var close = char.match(/\@/);
        if(_pos){
            if(_pos[0]=='>]'){
                pos = 9;
            }
            else if(_pos[0]=='>>]'){
                pos = 10;
            }
            else if(_pos[0]=='>>>]'){
                pos = 0x8;
            }
            else if(_pos[0]=='>>>>]'){
                pos = 0xe;
            }
        }
        else{
            _pos = char.match(/\[\<+/);
            if(_pos){
                if(_pos[0]=='[<')
                    pos = 0xc;
                else if(_pos[0]=='[<<')
                    pos = 0xb;
                else if(_pos[0]=='[<<<')
                    pos = 0xd;
                else if(_pos[0]=='[<<<<'){
                    pos = 0xf;
                }
            }
        }
        //console.log(_pos)
        char = char.replace('[','');
        char = char.replace(']','');
        char = char.replace('<','');
        char = char.replace('>','');
        char = char.replace('@','');
        var id = 1;
        if(角色对话头像[char]){
            id = 角色对话头像[char];
        }
        else{
            id = 角色表[char];
        }
        if(!charp[char]){
            newText += `%${hex(pos)}%%10%%${hex(id)}%%01%`;
            charp[char] = pos;
        }
        else{
            newText += `%${hex(charp[char])}%`;
        }
        if(close){
            newText += `%11%`;
        }

        //console.log(char);
        text = text.substr(a[0].length+a.index+1);
        num++;
    }while(1);
    return newText;
}

var textIdx =  0x1000;
var textCode = "";
var Escape = 37;    //'%'
var newText = (text)=>{
    if(typeof(text)=="number"){
        return text;
    }
    else if(!text){
        return undefined;
    }

    //如果遇到对话文本，则处理对话文本
    text = convertText(text);
    //text = "\n我们不是";
    var a = iconv.encode(text,"gbk");
    //console.log(a);
    var code = '';
    //console.log(a);
    code += `/*${text}*/\n`;
    for(var i=0;i<a.length;){
        var v = a[i];
        if(v==10){ //\n
            if(a[i+1]==10){ //\n\n
                i += 2;
                code += '0x3,0x1,\n\n'
                //console.log(1111111);
            }
            else{ //\n
                i += 1;
                code += '0x1,\n';
            }
        }
        else if(v!=Escape){
            code += '0x'+v.toString(16) + ',';
            i++;
        }
        else{
            code += `0x${String.fromCharCode(a[i+1])}${String.fromCharCode(a[i+2])},`;
            i+=4;
        }
    };

    textCode += `
    [0x${textIdx.toString(16)} - textStart] = (int)(const char[]){${code} 0},
`;
    //console.log(text);
    //console.log(textCode);
    return textIdx++;
}

export var newtext = newText;

var portrait_file = fs.createWriteStream(`${__dirname}/../hack/portrait_def.h`);
var portrait_set_file = fs.createWriteStream(`${__dirname}/../hack/portrait_set.h`);
var mini_portrait_data = fs.createWriteStream(`${__dirname}/../hack/mini_portrait_data.h`);
var mini_portrait_def = fs.createWriteStream(`${__dirname}/../hack/mini_portrait_def.h`);
var _140portrait_set = fs.createWriteStream(`${__dirname}/../hack/_140portrait_def.h`);
var _140portrait_data = fs.createWriteStream(`${__dirname}/../hack/_140portrait_data.h`);
var file召唤 = fs.createWriteStream(`${__dirname}/../hack/sum.h`);
var file召唤道具 = fs.createWriteStream(`${__dirname}/../hack/sum_item.h`);
var file召唤职业 = fs.createWriteStream(`${__dirname}/../hack/sum_class.h`);
var file道具限制 = fs.createWriteStream(`${__dirname}/../hack/item_limit.h`);
var file魔法武器 = fs.createWriteStream(`${__dirname}/../hack/item_magic.h`);
var file角色动画 = fs.createWriteStream(`${__dirname}/../hack/char_anime.h`);
var file图标 = fs.createWriteStream(`${__dirname}/../hack/icon_data.h`);

class EventCond{
    code:string;
    constructor(){
        this.code = '@事件条件--\n';
    }
    处理事件(事件:()=>any):any{
        var bak_code = current.code;
        current.code = '\n'; //初始化当前事件的代码
        事件();
        evt.返回();         //结束事件
        evt.结束事件();
        var code = current.code;
        current.code = bak_code;
        return code;
    }

    生成条件(标识:number,type:number,arg:any[],事件:(()=>any)|string|number):any{
        var sym = alloc_sym();
        if(
            typeof(事件)=="number"
            || typeof(事件)=="string"
        ){
            sym = `${事件}`;
        }
        arg[1] = arg[1]||0;
        this.code += `
@章节事件条件
.short  ${type}
.short  ${标识}
.int    ${sym}
.short  0x${arg[0].toString(16)}
.short  0x${arg[1].toString(16)}
`;
        if(arg[2]!=undefined&&arg[2]!=null){
            if(typeof(arg[2])=="number"){
            this.code += `
.int    0x${arg[1].toString(16)}
`;
            }
            else{
                this.code += `
.int    ${arg[2]}
 `;
            }
        }
        if(
            typeof(事件)=="number"
            ||typeof(事件)=="string"
        ){
            //如果为数字，则退出
            return;
        }
        var code = this.处理事件(事件);
        addasm(`
@章节事件结构体
@--事件
        .align 2
${sym}:
        ${code}`
        );
        return sym;
    }

    GameOver(标识:number,事件:()=>any):any{
        this.生成条件(标识,0x1,[0x65],事件);
    }
    消灭所有敌人(标识:number,事件:()=>any):any{
        this.生成条件(标识,0x1,[0x6],事件);
    }
    BOSS死亡(标识:number,事件:()=>any):any{
        this.生成条件(标识,0x1,[0x2],事件);
    }

    角色相邻时(标识:number,id1,id2,条件标识:number|undefined|null,事件:()=>any):any{
        id1 = get_char(id1);
        id2 = get_char(id2);
        条件标识 = 条件标识 | 0;
        this.生成条件(标识,0x3,[(id1)|(id2<<8),条件标识,0],事件);
    }

    宝箱(x:number,y:number,item:any):any{
        item = get_item(item);
        this.生成条件(0,0x7,[(x)|(y<<8),0x14],item);
    }

    商店(x:number,y:number,item:[],type:number){
        var sym = alloc_sym();
        this.生成条件(0,0x7,[(x)|(y<<8),type],sym);
    }

    密码商店(x:number,y:number,item:[]){
        this.商店(x,y,item,0x18);
    }

    道具店(x:number,y:number,item:[]){
        this.商店(x,y,item,0x17);
    }

    武器店(x:number,y:number,item:[]){
        this.商店(x,y,item,0x16);
    }

    村庄访问(标识:number,x:number,y:number,cb:()=>any){
        this.生成条件(标识,0x6,[
            (x)|(y<<8),0x10
        ],cb);

        //需要设置破坏(村庄被摧毁),应该是更新tile层
        this.生成条件(标识+1,0x5,[
            (x-1)|(y<<8),0x20 /* 0x20 被盗贼摧毁 */
        ],0x1);
    }

    占领(标识:number,x:number,y:number){
        this.生成条件(标识,0x5,[
            (x)|(y<<8),0x11  /* 0x11占领  */
        ],0x1);
    }

    开门(x:number,y:number){
        this.生成条件(0,0x8,[
            (x)|(y<<8),0x12  /*0x12 显示开门 */
        ],1);
    }

    回合(标识:number,回合:number[],处理:{
        我方回合:boolean,
        敌方回合:boolean,
        友方回合:boolean,
    }|undefined|null,event:()=>any):any{
        回合[0] = 回合[0] || 0;
        回合[1] = 回合[1] || 0;
        var vv = 0;
        if(处理.敌方回合){
            vv = 0x80;
        }
        if(处理.友方回合){
            vv = 0x40;
        }
        //其他的都是我方
        this.生成条件(标识,0x2,[(回合[0])|(回合[1]<<8),vv],event);
    }
};

export var set图标 = {
设置图标:(idx:number,png_16color_path)=>{
    var png2agb = spawn(`${__dirname}/../tools/png2agb.exe`,[
    `${__dirname}\\..\\图标\\${png_16color_path}`,
    `-o`,`${__dirname}\\..\\hack\\${png_16color_path}.bin`,
    `-t`
    ]);
    //var sym = alloc_sym();
    var code = '';
    png2agb.stdout.on("data",(data)=>{
        code += data.toString();
    });

    png2agb.stdout.on("end",()=>{
        file图标.write(`
[${idx}] = (u32)(const u8[]){${code}},
`);
    });
},
};

export var set角色 = {
设置角色:(索引,角色名,介绍,支援显示职业)=>{
    角色表[角色名] = 索引;
    var data:any = {
        角色名:角色名,
        id:索引,
        介绍:介绍,
        支援显示职业:支援显示职业,
    };
    角色[索引] = data;
    var d = {
        createASM:(asm:fs.WriteStream)=>{
            //console.log("创建角色",data.角色名);
            //var asm = fs.createWriteStream(__dirname+"/../hack/char.h");
            var index = newText(data.角色名);
            var 大头像 = 0;
            var 小头像 = data.小头像;
            var a = data.特技 || 0;
            var 支援:any = 0;
            //设置支援
            if(data.支援){
                //存在支援
                var vv:any[] = data.支援;
                支援 = '';
                var idx = vv.length;
                var num = vv.length;
                while(idx<7){
                    var v:any = [0,0];
                    vv[idx++] = v;
                }

                for(idx=0;idx<7;idx++){
                    //vv[idx][0] = vv[idx][0] | 0;    //角色
                    //vv[idx][1] = vv[idx][1] | 2;    //每回合支援增长
                    vv[idx][0] = getvalue(vv[idx][0],0);
                    vv[idx][1] = getvalue(vv[idx][1],2);
                }

                vv.forEach((v)=>{
                    //支援人物
                    支援 += `${get_char(v[0])},`;
                });
                vv.forEach((v)=>{
                    支援 += `${0},`; //未知，应该是跟攻击力有关
                });

                vv.forEach((v)=>{
                    支援 += `${(v[1])},`;   //支援经验增长
                });
                支援 += `${num},`;      //多少人

                支援 = `(u32)(const u8[]){${支援}}`;
            }

            var code = ``;
            var addcode = (name,value,comment?)=>{
                if(comment){
                    comment = `/*${comment}*/`;
                }
                else{
                    comment = "";
                }
                if(value||value==0){
                    code += `${comment}
[${data.id}].${name} = ${value},
`;
                }
            };
            var TT = (text)=>{
                if(typeof(text)=="string"){
                    return text.trim();
                }
                return text;
            }

            addcode("u00_",newText(data.角色名),`角色名:${data.角色名}`);
            addcode("u02_",newText(TT(data.介绍)));
            addcode("u05_",data.支援显示职业);
            addcode('u06_',data.大头像);
            addcode('u08_',data.小头像);
            addcode('u09_',data.属性);
            if(data.基本能力){
                addcode("u0B_",data.基本能力.a等级);
                addcode("u0C_",data.基本能力.aHP);
                addcode("u0D_",data.基本能力.a力量);
                addcode("u0E_",data.基本能力.a技术);
                addcode("u0F_",data.基本能力.a速度);
                addcode("u10_",data.基本能力.a守备);
                addcode("u11_",data.基本能力.a魔防);
                addcode("u12_",data.基本能力.a运气);
                addcode("u13_",data.基本能力.a体格);
            }

            if(data.武器熟练度){
                var pw = (v)=>{
                    if(typeof(v)=="number"){
                        return v;
                    }
                    if(v=='s'||v=='S'){
                        return 251;
                    }
                    else if(v=='a'||v=='A'){
                        return 181;
                    }
                    else if(v=='b'||v=='B'){
                        return 121;
                    }
                    else if(v=='c'||v=='C'){
                        return 71;
                    }
                    else if(v=='d'||v=='D'){
                        return 31;
                    }
                    else if(v=='e'||v=='E'){
                        return 1;
                    }
                    return 0;
                }
                addcode("u14_",pw(data.武器熟练度.剑));
                addcode("u15_",pw(data.武器熟练度.枪));
                addcode("u16_",pw(data.武器熟练度.斧));
                addcode("u17_",pw(data.武器熟练度.弓));
                addcode("u18_",pw(data.武器熟练度.杖));
                addcode("u19_",pw(data.武器熟练度.理));
                addcode("u1A_",pw(data.武器熟练度.光));
                addcode("u1B_",pw(data.武器熟练度.暗));
            }

            if(data.成长率){
                addcode("u1C_",data.成长率.aHP)
                addcode("u1D_",data.成长率.a力量)
                addcode("u1E_",data.成长率.a技术)
                addcode("u1F_",data.成长率.a速度)
                addcode("u20_",data.成长率.a守备)
                addcode("u21_",data.成长率.a运气)
                addcode("u22_",data.成长率.a魔防)
            }

            if(data.职业动画){
                var d:any[] = data.职业动画;
                var item_anime:any[] = d[9];
                var cc = '';
                if(item_anime){
                    //如果存在道具动画，则先把道具设置好
                    //item_anime.forEach((v,k)=>{
                    for(var i=0;i<item_anime.length;i+=2){
                        if(item_anime[i+1]==undefined||item_anime[i+1]==null){
                            continue;
                        }
                        var anime = item_anime[i+1];
cc    +=  `
0x${item_anime[i+0].toString(16)},${anime},
`;
                    };
                }
                //武器的动画
                for(var i=0;i<9;i++){
                    var anime = d[i];
                    if(anime!=undefined&&anime!=null){
                    cc += `
0x100+0x${i.toString(16)},${anime},
`;
                    }
                }
                //最后置为0
                cc += `
0,0,0,0
`;
                cc = `
[${data.id}] = (u32)(const u16[]){
${cc}
},
`;
                file角色动画.write(cc);
            }

            if(支援){
                addcode('u2C_',支援);
            }
            if(data.特技!=undefined){
                var v = data.特技;
                addcode('u28_',v&0xff)
                addcode('u29_',(v>>8)&0xff)
                addcode('u2A_',(v>>16)&0xff)
                addcode('u2B_',(v>>24)&0xff)
            }
            asm.write(code);
        },
        设置小头像:(png_path)=>{
            //data.小头像 = data.id;
            data.大头像 = data.id;
            var png2agb = spawn(`${__dirname}/../tools/png2agb.exe`,[
                `${__dirname}\\..\\头像\\${png_path}`,
            `-o`,`${__dirname}\\..\\hack\\${png_path}.bin`]);
            var sym = alloc_sym();



            var out = //fs.createWriteStream(`${__dirname}/../hack/${sym}.h`);
                mini_portrait_data;

            mini_portrait_def.write(`
[${data.id}] = {
    ${sym}_tile_data,
    ${sym}_pal,
},
`);
            out.write(`
            #undef agb_pal
            #undef tile_data
            #define agb_pal     ${sym}_pal
            #define tile_data   ${sym}_tile_data
            #include "data_${sym}.h"
    `);
            console.log(`${png_path} ${sym}`)
            var file = fs.createWriteStream(`${__dirname}/../hack/data_${sym}.h`);
            png2agb.stdout.on("data",(data)=>{
                file.write(data.toString());
            });
            png2agb.stderr.on("data",(data)=>{

            });

        },
        设置ID对话头像:(id)=>{
            角色对话头像[data.角色名] = id;
        },
        设置对话头像:(png_path)=>{
            //data.对话头像 = png_path;
            //生成图片
            var png2agb = spawn(`${__dirname}/../tools/png2agb.exe`,[
                '-size',    // 画布模式  -size <大小>
                '120x80',
                "-l",
                "120",
                "-h",
                '-i',       //-i <位置> <文件>
                '0x0',
                `${__dirname}\\..\\头像\\${png_path}`,
            `-o`,`${__dirname}\\..\\hack\\${png_path}.bin`]);

            //申请一个符号
            var sym = alloc_sym();
            portrait_file.write(`
//第一次定义，需要把数据全包括了
#undef COLOR_SET
#undef color_start
//定义别名
#define draw_pal ${sym}_draw_pal
#define linepal ${sym}_linepal
#define draw_tile ${sym}_tile

//引用数据生成第一个头像对话
#include "${sym}.h"


//第二次生成一个tile2数据
#undef draw_tile
#define draw_tile ${sym}_tile2
#define COLOR_SET
#define color_start 128
#include "${sym}.h"

#undef draw_pal
#undef linepal
#undef draw_tile

`);
            portrait_set_file.write(`
[${data.id}] = {
size_120x80,${sym}_draw_pal,{
    ${sym}_tile,${sym}_tile2,${sym}_tile,${sym}_tile
},${sym}_linepal
},
`);
            var out = fs.createWriteStream(`${__dirname}/../hack/${sym}.h`);
            console.log(`${sym}${png_path}\n`)
            png2agb.stdout.on("data",(data)=>{
                //console.log(data.toString());
                out.write(data.toString());
                //out.close();
            });
            png2agb.stderr.on("data",(data)=>{
                //console.log(data.toString());
            });
        },
        设置头像:(png_path)=>{
            //data.头像 = png_path;
            var sym = alloc_sym();

            var png2agb = spawn(`${__dirname}/../tools/png2agb.exe`,[
                `${__dirname}\\..\\头像\\${png_path}`,
            `-o`,`${__dirname}\\..\\hack\\${png_path}.bin`]);
            var initd = false;
            var outcode = "";
            var file = fs.createWriteStream(`${__dirname}/../hack/data_${sym}.h`);

            _140portrait_data.write(`
            #undef draw_pal
            #undef draw_tile
            #undef linepal
            #define draw_pal ${sym}_pal
            #define draw_tile ${sym}_tile
            #define linepal ${sym}_linepal
            #include "data_${sym}.h"
            `);
            png2agb.stdout.on('data',(data)=>{
                if(!initd){
                    initd = true;
                };
                //outcode += data.toString();
                file.write(data.toString());
                //_140portrait_data.write(data.toString());
            });

            png2agb.stdout.on("end",()=>{
            });

//设置
_140portrait_set.write(`
[${data.id}] = {
    ${sym}_tile,sizeof(${sym}_tile),
    ${sym}_pal,${sym}_linepal,
},
`);
        },
        基本能力:(v = {
            a等级:1,
            aHP:16,
            a力量:5,
            a技术:5,
            a速度:5,
            a守备:5,
            a魔防:5,
            a运气:0,
            a体格:5,
            a魔力:5,
        })=>{
            data.基本能力 = v;
        },
        人物特技:(v ={
            a再移动:false,
            a偷盗 : false,
            a使用盗贼钥匙 : false,
            a舞蹈 : false,
            a演奏 :false,
            a必杀加成 : false,
            a上位职业 : false,
            a运输队 : false,
            a战马 : false,
            a飞龙 : false,
            a飞马 : false,
            a压制 : false,
            a女性 : false,
            aboss : false,
            a魔王专用 : false,
            a剑士专用 : false,
            a龙_魔物专用 : false,
            a_10级 : false,
            a能力未知 : false,
            a三角攻击1 : false,
            a三角攻击2 : false,
            a瞬杀 : false,
            a封魔 : false,
            a召唤 : false,
            a女主角专用 : false,
            a男主角专用 : false,
            a琳专用 : false,
            a大贤者专用 : false,
        })=>{
            var t = {
                a再移动:1<<0,
                a偷盗 : 1<<2,
                a使用盗贼钥匙 : 1<<3,
                a舞蹈 : 1<<4,
                a演奏 :1<<5,
                a必杀加成 : 1<<6,
                a上位职业 : 1<<8,
                a运输队 : 1<<9,
                a战马 : 1<<10,
                a飞龙 : 1<<11,
                a飞马 : 1<<12,
                a压制 : 1<<13,
                a女性 : 1<<14,
                aboss : 1<<15,
                a魔王专用 : 1<<16,
                a剑士专用 : 1<<17,
                a龙_魔物专用 : 1<<18,
                a_10级 : 1<<19,
                a能力未知 : 1<<20,
                a三角攻击1 : 1<<21,
                a三角攻击2 : 1<<22,
                a瞬杀 : 1<<25,
                a封魔 : 1<<26,
                a召唤 : 1<<27,
                a女主角专用 : 1<<28,
                a男主角专用 : 1<<29,
                a琳专用 : 1<<30,
                a大贤者专用 : 1<<31,
            };
            var value = 0;
            for (const k in v) {
                if(v[k]){
                    value |= t[k];
                }
            }
            data.特技 = value;
        },
        支援人物:(a=[])=>{
            data.支援 = a;
        },
        武器熟练度:(v={
            剑 : 0,
            枪 : 0,
            斧 : 0,
            弓 : 0,
            杖 : 0,
            理 : 0,
            光 : 0,
            暗 : 0,
        })=>{
            data.武器熟练度 = v;
        },
        成长率:( v = {
            aHP:20,
            a力量:20,
            a技术:20,
            a速度:20,
            a守备:20,
            a运气:20,
            a魔防:20,
        })=>{
            data.成长率 = v;
        },
        扩展:{
            设置角色动画:(v:{
                a剑:number|string|undefined,
                a枪:number|string|undefined,
                a斧:number|string|undefined,
                a弓:number|string|undefined,
                a杖:number|string|undefined,
                a理:number|string|undefined,
                a光:number|string|undefined,
                a暗:number|string|undefined,
                a没有武器:number|string|undefined,
                a武器:[],
            })=>{
                var d = [];
                d.push(v.a剑);
                d.push(v.a枪);
                d.push(v.a斧);
                d.push(v.a弓);
                d.push(v.a杖);
                d.push(v.a理);
                d.push(v.a光);
                d.push(v.a暗);
                d.push(v.a没有武器);
                d.push(v.a武器);
                data.职业动画 = d;
            }
        },
    }
    角色列表.push(d);
    return d;
},
};

var eventList = {};
var current = {code:""};
var currentName = "";
var code = '';

var symbols = {};
var symbol_type = {};
var symbolT = {
none:0,
对话:1,
位置:2,
};


var symbol_codes = {};

var chapter_event = [{
    开始:{},结束:{},
    回合事件:[],
    角色对话:[],
    位置事件:[],
}];


var addasm = (c)=>{
    code += c;
    code += '\n';
};
var alloc_idx = 0;
//申请一个新符号
var alloc_sym = ()=>{
    alloc_idx ++;
    return "SYM_" + alloc_idx.toString();
}

//章节标志
var chapter_flg = 8;
var alloc_chapter_flg = ()=>{
    return chapter_flg++;
}

var label_num = 1;
var labelAlloc = ()=>{
    return label_num ++;
}

var get_char = (id)=>{
    if(typeof(id)=="string"){
        id = 角色表[id];
    }
    assert(typeof(id)=="number","未找到角色id");
    return id;
}

var get_class = (id)=>{
    if(typeof(id)=="string"){
        id = 职业表[id];
    }
    assert(typeof(id)=="number","未找到职业id");
    return id;
}

var get_item = (id)=>{
    if(typeof(id)=="string"){
        id = 道具表[id];
    }
    assert(typeof(id)=="number","未找到道具id");
    return id;
}

var 单位加载状态:any[]|undefined = undefined;

var evt = {
定义事件:(名字="")=>{
    if(!eventList[名字]){
        current = {code:""};
        eventList[名字] = current;
    }
    else{
        current = eventList[名字];
    }
},

createASM:()=>{
    //console.log(code);
    //创建事件
    //var file = fs.open(__dirname+"/../hack/chapter.h","w+",()=>{});

    var txtfile =fs.createWriteStream(__dirname+"/../hack/txt.h");
    var file = fs.createWriteStream(__dirname+"/../hack/chapter.h");
    var def = fs.createWriteStream(__dirname+"/../hack/chapter_def.h");
    var asm = fs.createWriteStream(__dirname+"/../hack/chapter.s");
    evt.定义事件("aaa");

    //处理角色
    var char_asm = fs.createWriteStream(__dirname+"/../hack/char.h");
    角色列表.forEach((v,k)=>{
        v.createASM(char_asm);
    });
    char_asm.close();

    var item_asm = fs.createWriteStream(__dirname+"/../hack/item.h");
    set道具.createASM(item_asm);


    var adddef = (name,comment?)=>{
        if(comment){
            def.write(`//${comment}\n`);
        }
        if(name){
            def.write(`extern const u8 ${name}[];\n`);
        }
    };

    chapter_event.forEach((v,k)=>{

        var sym = alloc_sym();
        var sym2 = alloc_sym();
        var sym_turn = alloc_sym();     //回合事件
        var sym_char = alloc_sym();     //角色事件
        var sym_pos = alloc_sym();      //位置事件
        var sym_move_start = alloc_sym();
        var sym_move_end = alloc_sym();

        //console.log(v);
        //console.log(eventList);
        var list:any[][] = [
            [sym,v.开始],
            [sym2,v.结束]
        ];

        //console.log(v.角色对话);

        list.forEach((v)=>{
            if(typeof(v[1])=="string"){
            asm.write(`
@${v[1]}
.global ${v[0]}
.align  2
${v[0]}:
${eventList[v[1]].code}
`);
                //设置返回
            asm.write(`
            @返回
            .byte 0|(2<<4)
            .byte 0x1
            .short 0
            `);
            }

        });



        var proc_event = (list:[],comment?,code?)=>{
            var new_sym = alloc_sym();
            asm.write(`
            .global ${new_sym}
            .align 2
            `);

            code = code || ""; //判断code是否有
            asm.write(`${new_sym}:
${code}
`);
            adddef(new_sym,comment);
            if(list){

                list.forEach((v,k)=>{
                    //导出符号

                    asm.write(`
    @对话处理 ${k}
    .global ${v}
    ${symbol_codes[v]}
    `);
                });
                return new_sym;
            }

            //有时候，空事件要设置处理
            asm.write(`
@结束
.short  0
.short  0
.int    0
.byte   0
.byte   0
.short  0
.short  0
.short  0
`);
            //添加事件
//             if(list){
//                 list.forEach((v,k)=>{
//                     asm.write(`

// `);
//                 });
//             }

            //return new_sym;
            return new_sym;
        }

        var ev = (<any>v).event_data;
        ev = ev || {};

        sym_char = proc_event(<any>v.角色对话,"对话结构",ev['u4_']);
        sym_turn = proc_event(<any>v.回合事件,"回合事件",ev['u0_']);
        sym_pos = proc_event(<any>v.位置事件,"位置事件",ev['u8_']);
        var sym_待机 = proc_event(null,"待机事件",ev['uC_']);
        var sym_移动开始 = proc_event(null,"移动开始",ev['u14_']);
        var sym_移动结束 = proc_event(null,"移动结束",ev['u18_']);
        var sym_关闭地图 = proc_event(null,"关闭地图",ev['u20_']);
        var sym_选定角色 = proc_event(null,"选定角色",ev['u10_']);
        sym_move_start = proc_event(undefined);
        sym_move_end = proc_event(undefined);
        //sym2 = "0";

        for (const key in eventList) {
            if(eventList[key].isdump){
                asm.write(eventList[key].code);
                //设置返回
                asm.write(`
    @返回
    .byte 0|(2<<4)
    .byte 0x1
    .short 0
`);
            }
        }

        asm.write(code);



        //console.log(k);
        if(v.开始){
// def.write(`
// extern const u8 ${sym}[];
// extern const u8 ${sym2}[];
// extern const u8 ${sym_turn}[];
// extern const u8 ${sym_char}[];
// extern const u8 ${sym_pos}[];
// extern const u8 ${sym_move_start}[];
// extern const u8 ${sym_move_end}[];
// `);
            adddef(sym);
            adddef(sym2);
            adddef(sym_turn);
            adddef(sym_char);
            adddef(sym_pos);
            adddef(sym_move_start);
            adddef(sym_move_end);
file.write(`
[${k}] = {
    //开始事件
    .u0_ = (void*)${sym_turn},      //回合切换
    .u4_ = (void*)${sym_char},      //对话
    .u8_ = (void*)${sym_pos},       //位置事件
    .uC_ = (void*)${sym_待机},      //待机事件
    .u10_   = (void*)${sym_选定角色},  //选定角色
    .u14_   = (void*)${sym_移动开始}, //移动开始
    .u18_   = (void*)${sym_移动结束}, //移动结束

    //.u1C_ 未找到数据定义
    .u20_ = (void*)${sym_关闭地图}, //未知数据定义
    .u24_ = (void*)${sym_关闭地图}, //未知数据定义
    .u48_ = (void*)${sym},      //开始
    .u4C_ = (void*)${sym2},     //结束

    //移动开始
    .u14_ = (void*)${sym_move_start},
    .u18_ = (void*)${sym_move_end},
},
`);
        }
    });
    txtfile.write(textCode);
    console.log("end!");
    setTimeout(()=>{
        console.log("end!");
    },2000);
},

创建事件:(type,arg=[],size=2)=>{
    evt.create(type,arg,size);
},
create:(type,arg=[],size=2)=>{
    var c = '';
    var eventName = (new Error()).stack.split("\n")[2].trim().split(" ")[1];
    if(size==2){
        arg[0] = arg[0]||0;
        arg[1] = arg[1]||0;

        c += `
@事件 ${eventName}
        .byte ${arg[0]}|(${size}<<4)
        .byte 0x${type.toString(16)}
        .short ${arg[1]} @0x${arg[1].toString(16)}
        `;
    }
    else{
        arg[0] = arg[0]||0;
        arg[1] = arg[1]||0;
        arg[2] = arg[2]||0;
        c+= `
@事件
        .byte   ${arg[0]}|(${size}<<4)
        .byte   0x${type.toString(16)}
        .short  ${arg[1]} @0x${arg[1].toString(16)}
        .int    ${arg[2]} @0x${arg[2].toString(16)}
        `;
    }
    //current += c;
    current.code += c;
},
设置章节开始事件:(index,名字="")=>{
    //assert(symbols[名字],"符号不存在");
    assert(eventList[名字],"事件不存在");
    //assert(symbol_type[名字]==symbolT.none,"必须为 <定义事件> 定义的事件");
    chapter_event[index] = chapter_event[index] || <any>{};
    chapter_event[index].开始 = 名字;
},

设置章节结束事件:(index,名字="")=>{
    // assert(symbols[名字],"符号不存在");
    // assert(symbol_type[名字]==symbolT.none,"必须为 <定义事件> 定义的事件");
    assert(eventList[名字],"事件不存在");
    chapter_event[index] = chapter_event[index] || <any>{};
    chapter_event[index].结束 = 名字;
},

设置章节对话事件:(index,名字="")=>{
    assert(symbols[名字],"符号不存在");
    assert(symbol_type[名字]==symbolT.对话,"必须为 <定义单位对话事件> 定义的事件");
    chapter_event[index] = chapter_event[index] || <any>{};
    chapter_event[index].角色对话 = chapter_event[index].角色对话 || [];
    chapter_event[index].角色对话.push(symbols[名字]);
},

设置章节回合事件:(index,开始回合,结束回合,事件:()=>any)=>{
    var sym = alloc_sym();
    var cc = `
    @回合事件
    .short 2
    .short 0        @一般不设置标识
    .int ${sym}     @申请的一个符号
    .short ${开始回合}|(${结束回合}<<8)
    .short 0
`;
    //备份事件
    var bak_current = current;
    current = {code:`${sym}:\n`};
    事件();
    //添加到汇编输出里
    addasm(current.code);
    current = bak_current;
    chapter_event[index].回合事件 = chapter_event[index].回合事件 || [];
    chapter_event[index].回合事件.push(cc);
},

定义单位在移动到指定范围事件:(名字,x1,y1,x2,y2)=>{
    var name = alloc_sym();
    var flg = alloc_chapter_flg();
    var code = '';
    //var num = 相互?1:2;
    symbols[名字] = alloc_sym();
    symbol_type[名字] = symbolT.对话;
    code += `
    @对话文本
    ${symbols[名字]}:
        .short  0xb
        .short  ${flg}
        .int    ${name}
        .byte   ${x1}
        .byte   ${y1}
        .byte   ${x2}
        .byte   ${y2}
    `;

    symbol_codes[symbols[名字]] = symbol_codes[symbols[名字]]||"";
    symbol_codes[symbols[名字]] += code;
},

定义单位对话事件:(名字="",角色1,角色2,相互=false,flga?)=>{
    var name = alloc_sym();
    var flg = flga;
    if(!flg){
        flg = alloc_chapter_flg();
    }
    else{
    }
    var code = '';
    var num = 相互?2:1;
    symbols[名字] = alloc_sym();
    symbol_type[名字] = symbolT.对话;
    evt.定义事件(名字);
    current.code += `${name}:`;
    (<any>current).isdump = true;

    for(var i=0;i<num;i++){
    code += `
@对话文本
${symbols[名字]}:
    .short  3
    .short  ${flg}
    .int    ${name}
    .byte   ${get_char(角色1)}
    .byte   ${get_char(角色2)}
    .short  0
    .short  0
    .short  0
`;
        var tmp = 角色1;
        角色1 = 角色2;
        角色2 = tmp;
    };
    symbol_codes[symbols[名字]] = symbol_codes[symbols[名字]]||"";
    symbol_codes[symbols[名字]] += code;
},

结束事件:()=>{
    evt.create(0x1,[0,0]);
},

过关:()=>{
    evt.设置标志(0x3);
},

GameOver:()=>{
    evt.调用外部事件(0x085B9EE8);
},

移动:(x,y)=>{
},

返回:()=>{
    evt.create(0x1,[0,0]);
},
//0x8
标签:(名称)=>{
    evt.create(0x8,[0,名称]);
},
//0x9
跳到标签:(标签)=>{
    evt.create(0x9,[0,标签]);
},
///////////////////////////////////////////////
//0xc
如果大于:(idx1,idx2,标签=0)=>{
    evt.create(0xc,[3,标签,(idx1)|(idx2)])
},
如果小于:(idx1,idx2,标签=0)=>{
    evt.create(0xc,[5,标签,(idx1)|(idx2)])
},
如果等于:(idx1,idx2,标签=0)=>{
    evt.create(0xc,[0,标签,(idx1)|(idx2)])
},
如果不等于:(idx1,idx2,标签=0)=>{
    evt.create(0xc,[1,标签,(idx1)|(idx2)])
},
如果大于等于:(idx1,idx2,标签=0)=>{
    evt.create(0xc,[2,标签,(idx1)|(idx2)])
},
如果小于等于:(idx1,idx2,标签=0)=>{
    evt.create(0xc,[43,标签,(idx1)|(idx2)])
},

//0x19
//配合0xc使用
获得回合数:()=>{
    evt.create(0x19,[3]);
},
是否在A路线:()=>{
    evt.create(0x19,[6]);
},

//0x03
//配合条件判断 0xc使用
获得标志:(offset)=>{
    evt.create(0x3,[1,offset]);
},

获得当前事件标志:(offset)=>{
    evt.create(0x3,[0,offset]);
},

//0x4
//配合0xc使用
获得随机数:(value=100)=>{
    evt.create(0x4,[0,value]);
},

//0x5
值复制:(idx1,idx2)=>{
    evt.create(0x5,[0,idx1|(idx2<<0x10)]);
},

//0x6
值加:(dest,idx1,idx2)=>{
    evt.create(0x6,[0,dest|(idx1<<8)|(idx2<<4)])
},

值减:(dest,idx1,idx2)=>{
    evt.create(0x6,[1,dest|(idx1<<8)|(idx2<<4)])
},

值乘:(dest,idx1,idx2)=>{
    evt.create(0x6,[2,dest|(idx1<<8)|(idx2<<4)])
},

值除:(dest,idx1,idx2)=>{
    evt.create(0x6,[3,dest|(idx1<<8)|(idx2<<4)])
},

值求余:(dest,idx1,idx2)=>{
    evt.create(0x6,[4,dest|(idx1<<8)|(idx2<<4)])
},

值位与:(dest,idx1,idx2)=>{
    evt.create(0x6,[5,dest|(idx1<<8)|(idx2<<4)])
},

值位或:(dest,idx1,idx2)=>{
    evt.create(0x6,[6,dest|(idx1<<8)|(idx2<<4)])
},

值位异或:(dest,idx1,idx2)=>{
    evt.create(0x6,[7,dest|(idx1<<8)|(idx2<<4)])
},

值左移:(dest,idx1,idx2)=>{
    evt.create(0x6,[8,dest|(idx1<<8)|(idx2<<4)])
},

值右移:(dest,idx1,idx2)=>{
    evt.create(0x6,[9,dest|(idx1<<8)|(idx2<<4)])
},

//////////////////////////////////////////////
//0xE
等待:(frame)=>{
    frame = frame || 0x3c;
    evt.create(0xe,[0,frame]);
},
//0x30
等待单位处理:()=>{
    evt.create(0x30,[0,0]);
},

////////////////////////
//0xd
执行ARM代码:(name)=>{
    evt.create(0xd,[0,0,name],4);
},

//////////////////////////////
//0x34
//尚未知道 a0=0xa,0xb,0xc
移除单位:(id)=>{
    id = get_char(id);
    evt.create(0x34,[0xf,id]);
},

设置单位为我方:(id)=>{
    id = get_char(id);
    evt.create(0x34,[2,id]);
},

设置单位为友方:(id)=>{
    id = get_char(id);
    evt.create(0x34,[3,id]);
},

设置单位为敌方:(id)=>{
    id = get_char(id);
    evt.create(0x34,[4,id]);
},

设置单位为已死亡:(id)=>{
    id = get_char(id);
    evt.create(0x34,[0xd,id]);
},

设置单位为已移动:(id)=>{
    id = get_char(id);
    evt.create(0x34,[0x6,id]);
},

设置单位消失:(id)=>{
    id = get_char(id);
    evt.create(0x34,[0xe,id]);
},


//0x17
背景淡出:(speed,白色=0)=>{
    evt.create(0x17,[白色?2:0,speed]);
},
背景淡入:(speed,白色=0)=>{
    evt.create(0x17,[白色?3:1,speed]);
},
//0x12
切换音乐:(id)=>{
    evt.create(0x12,[0,id]);
},


//25
// 切换地图:(id)=>{
//     evt.create(0x17,[0,id]);
// },
//////////////////////////
//0x1a
对话开始:()=>{
    evt.create(0x1a,[0,0]);
},
/////////////////////
//0x1b
/**
 * @param text string
 */
对话:(text=0xffff)=>{
    text = newText(text);
    evt.create(0x1b,[0,text]);
},
对话关闭:()=>{
    evt.create(0x1b,[2,0]);
},

//////////////////////////////
//扩展
///地图对话
对话_地图:(text=0xffff)=>{
    evt.对话开始();
    evt.对话(text);
    evt.create(0x1d,[0,0]); //必须加上这条指令，否则地图对话就不显示
    evt.对话关闭();
},


//////////////////////////
//0x3b
//光标移动
光标移动到角色:(id)=>{
    id = get_char(id);
    evt.create(0x3b,[1,id]);
},
光标关闭:()=>{
    evt.create(0x3b,[2]);
},
//0x5 设置栈值
// 0x30004B0    地址偏移的数据相当于寄存器   一共 12 个
//              0x30004e4 (相对0x30004B0第13个) 相当于sp，用于表示栈深度
//              0x30004e8 栈0
//              0x30004ec 栈1 ...
清空栈值:()=>{
    evt.create(0x5,[0,0xd,0],4);
},

值压栈:(src=0)=>{
    var eventType = 0x7;
    var len = 2;
    var arg = [1,0]; //arg[0] == 1 则把栈顶的值压栈,
                      //      ==0 则,把(int)[arg[1] * 4 + 0x30004B0] 压栈
                      //      ==2 [arg[1] * 4 + 0x30004B0] = 出栈值
    evt.create(0x7,[0,src]);
},

值压栈1:()=>{
    //等价于值压栈(1)
    evt.create(0x7,[1,0]);
},

值出栈:(dest=0)=>{
    evt.create(0x7,[2,dest]);
},

设置值:(offset,value)=>{
    var eventType = 0x5;
    var len = 4;
    var arg = [0,offset,value]; //0xd 位置为栈值
    evt.create(0x5,[0,offset,value],4);
},

/////////////////////////////////
//0x0a
调用外部事件:(name)=>{
    evt.create(0xa,[0,0,name],4);
},

////////////////////////////////
//0x02
设置标志:(offset)=>{
    var arg = [
        (1<<3)  //设置值
        |1,     //事件标识
        offset
    ];
    var type = 0x02;
    evt.create(type,arg);
},

取消标志:(offset)=>{
    var arg = [
        (0<<3)  //取消值
        |1,     //事件标识
        offset
    ];
    var type = 0x02;
    evt.create(type,arg);
},

设置当前事件标志:(offset)=>{
    var arg = [
        (1<<3)  //设置值
        |0,     //事件标识
        offset
    ];
    var type = 0x02;
    evt.create(type,arg);
},

取消当前事件标志:(offset)=>{
    var arg = [
        (0<<3)  //取消值
        |0,     //事件标识
        offset
    ];
    var type = 0x02;
    evt.create(type,arg);
},
////////////////////////////////
//0x1a
文本显示开始:()=>{

},
文本显示:()=>{

},
文本结束:()=>{

},

切换关卡:()=>{

},

//0x25
切换地图:(chapter)=>{
    evt.create(0x25,[0,chapter]);
},

//0x19
单位配置保存:()=>{

},

//0x2f
移动单位:(id,x,y,speed)=>{
    speed = speed | 0x8;
    id = get_char(id);
    var eventType = 0x2f;
    var len = 4;
    var arg = [0,speed,id|((x<<0x10)|(y<<0x18))];
    evt.create(eventType,arg,len);
},

移动单位到目标角色:(id,id2)=>{
    id = get_char(id);
    var eventType = 0x2f;
    var len = 4;
    var arg = [1,8,id|(id2<<0x10)];
    evt.create(eventType,arg,len);
},
往左移动单位:(id)=>{
    id = get_char(id);
    var eventType = 0x2f;
    var len = 4;
    var arg = [2,8,id];
    evt.create(eventType,arg,len);
},

往右移动单位:(id)=>{
    id = get_char(id);
    var eventType = 0x2f;
    var len = 4;
    var arg = [2,8,id|(1<<0x10)];
    evt.create(eventType,arg,len);
},

往上移动单位:(id)=>{
    id = get_char(id);
    var eventType = 0x2f;
    var len = 4;
    var arg = [2,8,id|(3<<0x10)];
    evt.create(eventType,arg,len);
},

往下移动单位:(id)=>{
    id = get_char(id);
    var eventType = 0x2f;
    var len = 4;
    var arg = [2,8,id|(2<<0x10)];
    evt.create(eventType,arg,len);
},

移动关闭单位:()=>{

},

///应该是配合传送使用
直接移动单位:(id,x:number,y:number)=>{
    id = get_char(id);
    evt.create(0x2f,[8,id,(x|(y<<8))<<0x10],4);
},

////////////////////////////
//0x12

///////////////////////////////
//0x3a 显示提示框
提示框:(id,value=0)=>{
    var eventType = 0x3a;
    var len = 4;
    var arg = [0,id,value];
    evt.create(eventType,arg,len);
},

关卡名:(id,x=10,y=0)=>{
    var eventType = 0x3a;
    var len = 4;
    var arg = [1,id,(x<<0x10)|(y<<0x18)];
    evt.create(eventType,arg,len);
},

提示信息:(id,x=10,y=0)=>{
    var eventType = 0x3a;
    var len = 4;
    var arg = [2,id,(x<<0x10)|(y<<0x18)];
    evt.create(eventType,arg,len);
},

///////////////////////
// a0=0xa,0xb,0xc 例子在8A61178上
//0x34
// 更换阵营:(id)=>{
// },

//////////////////////////
//0x37

给与:(id,item)=>{
    evt.设置值(3,item);
    var eventType = 0x37;
    var len = 2;
    var arg = [0,id];
    evt.create(eventType,arg,len);
},

扩展:{
    加载范围单位:(pos:number[],layout:string,cb:(idx:number,status:string,lv:number,x:number,y:number)=>any)=>{
        var line = layout.split("\n"); //
        var y = 0;
        var idx = 0;
        单位加载状态 = [];
        line.forEach((v,k)=>{
            if(v[0]!='-'){
                if(y<=pos[3]){
                    var x = 0;
                    for(x=0;x<pos[2];x++){
                        var s = v[x];
                        if(typeof(s)!="string"){
                            break;
                        }
                        if(s.trim()!=""){
                            var n = (<any>s)-<any>'0';
                            if(isNaN(n)){
                                n = 0;
                            }
                            cb(idx++,s,n,x+pos[0],y+pos[1]);
                        }
                    }
                    y++;
                }
            }
        });
        var units = 单位加载状态;
        单位加载状态 = undefined;
        e.加载单位(units);
    },
},

//0x2c
//随机: number          第一项等级 +- 波动
//范围: {x,y,w,h}       在这个范围内加载单位
加载单位:(a = [
    {
        a角色 : undefined,
        a职业 : undefined,
        a领导 : undefined,
        a等级修正 : 0,
        a我方 : undefined,
        a友方 : undefined,
        a敌方 : undefined,
        a等级 : 2,
        a坐标X : 0,
        a坐标Y : 0,
        a移动路线 : [{
            x : 0,
            y : 0,
            speed:8,
        }],
        a道具:[
        ],
        a游戏AI:{
            // 站着:false,
            // 进入攻击范围内攻击:false,
            // 治疗同伴:false,
            // 主动出击:false,
            // //进入射程后攻击:false,
            // 奋勇:false,
            // 第一回合不动:false,
            // 前两回合不动:false,
            能攻击则攻击:false, //0x3 如果没有攻击位置，则站着
            追击:false, //0xa,
            第二个回合出击:false, //0x12
            //0xA,0x12

            傻站着:false
        },
    }],随机?:boolean)=>{
        if(单位加载状态){
            单位加载状态 = [...单位加载状态,...a];  //添加到目标数组
            return;
        }

        var eventType = 0x2c;
        var arg:any[] = [0,0,0]; //分别是

        var sym = alloc_sym();
        arg[2] = sym;
        var asm = `
${sym}:
`;
    a.forEach((v)=>{
        var char = get_char(v.a角色);
        var _class = get_class(v.a职业);
        console.log(v.a职业);
        var fixed = v.a等级修正?1:0;
        v.a等级 = v.a等级 || 1;
        v.a等级 = v.a等级 > 0?v.a等级:1;
        var ch = 0;
        ch = v.a友方?1:ch;
        ch = v.a敌方?2:ch;
        var flg = 0;
        var movesym:any = 0;
        var move_num = 0;
        var item = [0,0,0,0];
        var ai = 0;
        v.a坐标X = v.a坐标X||0;
        v.a坐标Y = v.a坐标Y || 0;
        if(v.a游戏AI){
            if(v.a游戏AI.能攻击则攻击){
                ai = 3;
            }
            else if(v.a游戏AI.追击){
                ai = 0xa;
            }
            else if(v.a游戏AI.第二个回合出击){
                ai = 0x12;
            }
            else if(v.a游戏AI.傻站着){
                ai |= (0xc<<0x8);
            }
        }

        if(v.a道具){
            v.a道具.forEach((v,k)=>{
                item[k] = get_item(v);
            });
        }

        if(v.a移动路线){
            movesym = alloc_sym();
            move_num = v.a移动路线.length;
            var _code = `
            ${movesym}:
            `;
            v.a移动路线.forEach((v,k)=>{
                v.speed = v.speed||0;
                _code += `
                .int (${v.x})|(${v.y}<<6)|(${v.speed}<<12)
                .short 0
                .short 0
                `;
            });
            //添加到汇编中
            addasm(_code);
        }
    asm += `
    @加载单位
    .byte ${char}
    .byte ${_class}
    .byte 0
    @等级 ${v.a等级}
    .byte (${fixed})|(${ch}<<1)|(${v.a等级}<<3)
    .short (${v.a坐标X})|(${v.a坐标Y}<<6)|(${flg}<<12)
    .byte 0
    .byte ${move_num}
    .int  ${movesym}
    @ .byte ${v.a道具[0]},${v.a道具[1]},${v.a道具[2]},${v.a道具[3]}
    .byte ${item[0]},${item[1]},${item[2]},${item[3]}
    .int  ${ai}
    `
    });

    //最后，需要添加一个空的单位
    asm += `
    @结束加载
    .byte 0
    .byte 0
    .byte 0
    .byte 0
    .short 0
    .byte 0
    .byte 0
    .int  0
    .byte 0,0,0,0
    .int  0
    `;

    //添加到汇编中
    addasm(asm);
    evt.create(eventType,arg,4);
},

战斗动画:(左边角色id,右边角色id,a=[
    {
        a攻击方:undefined,        //攻击方 ,0为左边，1右方
        MISS:undefined,           //攻击是否miss
        a命中:undefined,          //
        a必杀:undefined,          //
        a瞬杀动画:undefined,       //
        a特效攻击动画:undefined,   //
        a特效防御盾:undefined,     //
        a伤害:undefined,          //如果为0，则正常计算，负数表示没有伤害
    },
])=>{
    if(a.length>0){
        //在这里设置战斗
        evt.清空栈值();

        a.forEach((v,k)=>{
            var value = 0;
            value |= v.a攻击方||0;
            value |= (v.a伤害||0)<<8;
            if(v.a必杀)
                value |= (1)<<16;
            else if(v.MISS)
                value |= (2)<<16;

            if(v.a瞬杀动画){
                value |= 0x8000000;
            }
            else if(v.a特效攻击动画){
                value |= 0x40000000;
            }
            else if(v.a特效防御盾){
                value |= 0x80000000;
            }

            evt.设置值(1,value);
            evt.值压栈();
        });
        //结束动画
        evt.设置值(1,0xffffffff);
        evt.值压栈();
    }
    var eventType = 0x3f;
    var arg = [0,左边角色id,右边角色id]; //分别是
    evt.create(eventType,arg,4);
},

镜头移动:(x,y)=>{
    evt.create(0x26,[0,(x)|(y<<8)]);
},

镜头移动到角色:(id)=>{
    id = get_char(id);
    evt.create(0x26,[1,id]);
},

/////////////////////////
//0x41
传送动画:(POS?:{X:number,Y:number})=>{
    var value = 0xffff;
    if(POS){
        value = POS.X | (POS.Y<<8);
    }

    evt.create(0x41,[0,value]);
},

传送结束动画:(POS?:{X:number,Y:number})=>{
    var value = 0xffff;
    if(POS){
        value = POS.X | (POS.Y<<8);
    }
    evt.create(0x41,[1,value]);
},
//////////////////////////////////////
//0x33
获得角色位置至C:(id)=>{
    id = get_char(id);
    evt.create(0x33,[6,id]);
},

获得角色阵营至C:(id)=>{
    id = get_char(id);
    evt.create(0x33,[5,id]);
},

获得角色职业至C:(id)=>{
    id = get_char(id);
    evt.create(0x33,[7,id]);
},

//还有其他

///////////////////////////////////
//扩展事件
传送出:(角色)=>{
    // [2]  角色id
    // [11] 目标位置
    //var value = x|(y<<0x10);
    //evt.设置值(11,value);
    evt.设置值(2,get_char(角色));
    evt.调用外部事件(0x8a60654); //会自动获取坐标
},

传送:(角色,x:number,y:number)=>{
    var id = get_char(角色);
    evt.传送出(id);
    evt.设置值(2,id);
    evt.create(0x2f,[8,0xffff,0xfffd|((x|(y<<8))<<0x10)],4); //这里是直接移动单位到目标位置
    evt.调用外部事件(0x08a60630);
},

If:(idx1,cmp:string,idx2,cb:()=>any,else_cb?:()=>any)=>{
    //申请一个标签
    var label = labelAlloc();
    var ccb = e.如果等于;
    if(cmp=='<')
        ccb = e.如果大于等于;
    else if(cmp=='>')
        ccb = e.如果小于等于;
    else if(cmp=='==')
        ccb = e.如果不等于;
    else if(cmp=='!=')
        ccb = e.如果等于;
    else if(cmp=='>=')
        ccb = e.如果小于;
    else if(cmp=='<=')
        ccb = e.如果大于;
    ccb(idx1,idx2,label);
    //处理事件
    cb();
    if(else_cb){
        var label2 = labelAlloc();
        e.跳到标签(label2);
        e.标签(label);
        else_cb();
        e.标签(label2);
    }
    else{
        e.标签(label);
    }
},

// 添加事件:(type:number,)=>{
// },

// 消灭BOSS触发:(关卡:number,cb:()=>any)=>{
//     //混合事件，type = 0x1, 0x2

// },

// 消灭所有敌人触发:(关卡:number,cb:()=>any)=>{

// },

// GameOver触发:(关卡:number,cb:()=>any)=>{

// },

// 回合切换触发:(关卡:number,回合范围:[],cb:()=>any)=>{

// },

// 移动到目标位置触发:(关卡:number,位置:{x:number,y:number,x2:number,y2:number}|null|undefined,cb:()=>any)=>{
// },

// 待机时触发:(光卡:number,位置:{x:number,y:number,x2:number,y2:number}|undefined|null,cb:()=>any)=>{
// },

章节事件触发:(index:number)=>{
        //初始化
        var ev:any = chapter_event[index];
        ev = ev || {};
        chapter_event[index] = ev;

        var asm:any = ev.event_data || {}; //初始化，如果存在，则不需要初始化
        var add_asm = (key:string,code:string)=>{
            asm[key] = asm[key] || "";
            asm[key] += code;
        }
        ev.event_data = asm;

        return{
        /**
         * 回合切换时触发，(我方回合，友方回合，敌方回合).
         */
        回合切换时:(cb:(cond:EventCond)=>any)=>{
            var cond = new EventCond();
            cb(cond);
            add_asm("u0_",cond.code);
        },

        /**
         * 针对人物对话
         */
        人物相邻:(cb:(cond:EventCond)=>any)=>{
            var cond = new EventCond();
            cb(cond);
            add_asm("u4_",cond.code);
        },

        /**
         * 移到目标位置时触发(未待命)
         */
        移动到目标位置:(cb:(cond:EventCond)=>any)=>{
            var cond = new EventCond();
            cb(cond);
            add_asm("u8_",cond.code);
        },
        /**
         * 移到目标位置时待机时触发(未待命)
         */
        待命时:(cb:(cond:EventCond)=>any)=>{
            var cond = new EventCond();
            cb(cond);
            add_asm("u10_",cond.code);
        },
        /**
         * 移动前触发
         */
        移动前:(cb:(cond:EventCond)=>any)=>{
            var cond = new EventCond();
            cb(cond);
            add_asm("u14_",cond.code);
        },
        /**
         * 移动后触发
         */
        移动后:(cb:(cond:EventCond)=>any)=>{
            var cond = new EventCond();
            cb(cond);
            add_asm("u18_",cond.code);
        }
    };
},

};

export var e = evt;